package com.csun.cmny.provider.controller.admin;



import com.csun.cmny.core.annotation.ValidateAnnotation;

import com.csun.cmny.core.support.BaseController;
import com.csun.cmny.provider.model.domain.*;
import com.csun.cmny.provider.model.dto.merchant.*;
import com.csun.cmny.provider.model.vo.merchant.MerchantTimeVo;
import com.csun.cmny.provider.model.vo.merchant.MerchantVo;
import com.csun.cmny.provider.resolver.CmnyMessageSource;
import com.csun.cmny.provider.service.*;

import com.csun.cmny.provider.utils.LocationUtils;
import com.csun.cmny.provider.utils.Md5Util;
import com.csun.cmny.provider.utils.OnOffTimeUtil;
import com.csun.cmny.util.PublicUtil;
import com.csun.cmny.util.RedisKeyUtil;
import com.csun.cmny.util.RedisUtil;
import com.csun.cmny.util.wrapper.WrapMapper;
import com.csun.cmny.util.wrapper.Wrapper;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.MediaType;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpSession;
import javax.validation.Valid;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

import static java.util.Map.Entry.comparingByValue;
import static java.util.stream.Collectors.toMap;

@RestController
@RequestMapping(value = "/merchant", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public class UacMerchantController extends BaseController {

    @Resource
    private UacMerchantService merchantService;
    @Resource
    private CmnyMessageSource cmnyMessageSource;
    @Resource
    private UacFirstLvelMerchantBindService firstLvelMerchantBindService;
    @Resource
    private UacUserService userService;
    @Resource
    private UacSecondLvelMerchantBindService secondLvelMerchantBindService;
    @Resource
    private RedisTemplate<String,Object> redisTemplate;
    @Resource
    private UacUserTokenService uacUserTokenService;



    @ValidateAnnotation
    @ApiOperation(httpMethod = "POST", value = "商户新增")
    @RequestMapping(value = "/add", method = RequestMethod.POST)
    public Wrapper addOmcContract(@RequestBody @Valid MerchantSaveDto merchantSaveDto, BindingResult br) throws ParseException {

        merchantSaveDto.setGroupId(getLoginAuthDto().getGroupId());
        merchantSaveDto.setUserName(getLoginAuthDto().getUserName());
        merchantSaveDto.setUserId(getLoginAuthDto().getUserId());

        /*校验此身份证号是否被注册过*/
        UacMerchant merchantIdCard = new UacMerchant();
        merchantIdCard.setPrincipalIDCard(merchantSaveDto.getPrincipalIDCard());
        List<UacMerchant> uacMerchants = merchantService.select(merchantIdCard);
        if(PublicUtil.isNotEmpty(uacMerchants)){
            return WrapMapper.wrap(Wrapper.ERROR_CODE,cmnyMessageSource.getMessage("merchant.PrincipalIDCard.error", null));
        }


        /*校验此名称的商家是否被使用过*/
        UacMerchant merchant = new UacMerchant();
        merchant.setMerchantName(merchantSaveDto.getMerchantName());
        List<UacMerchant> select = merchantService.select(merchant);

        if(PublicUtil.isNotEmpty(select)){

            return WrapMapper.wrap(Wrapper.ERROR_CODE,cmnyMessageSource.getMessage("merchant.name.error", null));
        }

        /*校验此手机号是否注册过*/
        UacMerchant merchant1 = new UacMerchant();
        merchant1.setPrincipalPhone(merchantSaveDto.getPrincipalPhone());
        List<UacMerchant> select1 = merchantService.select(merchant1);

        if(PublicUtil.isNotEmpty(select1)){
            return WrapMapper.wrap(Wrapper.ERROR_CODE,cmnyMessageSource.getMessage("merchant.principalPhone.error", null));
        }

        /*校验此手机号作为的用户名是否被使用过*/
        UacUser user = new UacUser();
        user.setLoginName(merchantSaveDto.getPrincipalPhone());
        List<UacUser> uacUsers = userService.select(user);
        if(PublicUtil.isNotEmpty(uacUsers)){
            return WrapMapper.wrap(Wrapper.ERROR_CODE,cmnyMessageSource.getMessage("merchant.principalPhone.error", null));
        }



        //新增商家对应信息
        int save = merchantService.insertMerchant(merchantSaveDto);




        return WrapMapper.wrap(Wrapper.SUCCESS_CODE,cmnyMessageSource.getMessage("operation.success", null),save);
    }

    @ValidateAnnotation
    @ApiOperation(httpMethod = "POST", value = "商户分页查询")
    @RequestMapping(value = "/select", method = RequestMethod.POST)
    public Wrapper select(@RequestBody @Valid MerchantQueryDto merchantQueryDto){

        //若未传机构id，默认置为登陆账号机构id
        if(PublicUtil.isEmpty(merchantQueryDto.getGroupId())){
            merchantQueryDto.setGroupId(getLoginAuthDto().getGroupId());
        }

        List<MerchantVo> list=merchantService.selectMerchant(merchantQueryDto);

        for (MerchantVo merchantVo : list) {
            UacSecondLvelMerchantBind uacSecondLvelMerchantBind = new UacSecondLvelMerchantBind();
            uacSecondLvelMerchantBind.setMerchantId(merchantVo.getId());
            List<UacSecondLvelMerchantBind> select = secondLvelMerchantBindService.select(uacSecondLvelMerchantBind);
            ArrayList<Long> longs = new ArrayList<>();
            for (UacSecondLvelMerchantBind secondLvelMerchantBind : select) {
                longs.add(secondLvelMerchantBind.getSecondLevelId());
            }
            merchantVo.setSecondLevelIds(longs);

        }
        PageInfo<MerchantVo> pageInfo = new PageInfo<>(list);


        return WrapMapper.wrap(Wrapper.SUCCESS_CODE,cmnyMessageSource.getMessage("operation.success", null),pageInfo);
    }

    @ValidateAnnotation
    @ApiOperation(httpMethod = "POST", value = "商户修改")
    @RequestMapping(value = "/update", method = RequestMethod.POST)
    public Wrapper update(@RequestBody @Valid MerchantUpdateDto merchantUpdateDto, BindingResult br) throws ParseException {

        UacMerchant uacMerchant = new UacMerchant();

        uacMerchant.setMerchantName(merchantUpdateDto.getMerchantName());

        List<UacMerchant> select = merchantService.select(uacMerchant);



        if(PublicUtil.isNotEmpty(select)){
            if(!select.get(0).getId().equals(merchantUpdateDto.getId())){
                return WrapMapper.wrap(Wrapper.ERROR_CODE,cmnyMessageSource.getMessage("merchant.name.error", null));
            }
        }


        UacMerchant merchant = new UacMerchant();

        BeanUtils.copyProperties(merchantUpdateDto,merchant);

        int update = merchantService.update(merchant);

        //将修改的商家信息写入redis
        if (PublicUtil.isNotEmpty(merchant)){
            redisTemplate.opsForValue().set(RedisKeyUtil.getUacMerchant(uacMerchant.getId().toString()),merchant);
        }


        return WrapMapper.wrap(Wrapper.SUCCESS_CODE,cmnyMessageSource.getMessage("operation.success", null),update);
    }

    @ValidateAnnotation
    @ApiOperation(httpMethod = "POST", value = "删除商户")
    @RequestMapping(value = "/delet", method = RequestMethod.POST)
    public Wrapper delet(Long id) {

       /* if (!StringUtils.isEmpty(accessToken)) {
            // 修改用户在线状态
            UserTokenDto userTokenDto = uacUserTokenService.getByAccessToken(accessToken);
            userTokenDto.setStatus(UacUserTokenStatusEnum.OFF_LINE.getStatus());
            uacUserTokenService.updateUacUserToken(userTokenDto, getLoginAuthDto());

            redisTemplate.delete(RedisKeyUtil.getAccessTokenKey(accessToken));
        }*/

       int result=merchantService.deleteMerchant(id);

       //删除对应的redis信息
        redisTemplate.delete(RedisKeyUtil.getUacMerchant(id.toString()));


        return WrapMapper.wrap(Wrapper.SUCCESS_CODE,cmnyMessageSource.getMessage("operation.success", null),result);
    }

    @ValidateAnnotation
    @ApiOperation(httpMethod = "POST", value = "修改商户密码")
    @RequestMapping(value = "/updatePassword", method = RequestMethod.POST)
    public Wrapper updatePassword(Long id,String password,String confirmPassword){

        //判定两次输入的密码是否一致
        if(!password.equals(confirmPassword)){
            return WrapMapper.wrap(Wrapper.ERROR_CODE,cmnyMessageSource.getMessage("merchant.password.error", null));
        }

        UacMerchant uacMerchant = merchantService.selectByKey(id);

        //判定商户是否存在
        if (PublicUtil.isEmpty(uacMerchant)){
            return WrapMapper.wrap(Wrapper.ERROR_CODE,cmnyMessageSource.getMessage("merchant.is.null", null));
        }

        //判定更改过的密码和原密码是否相同
        UacUser user = userService.selectByKey(uacMerchant.getUserIdBind());
        String newPassWord = Md5Util.encrypt(password);

        if (Md5Util.matches(password,user.getLoginPwd())){
            return WrapMapper.wrap(Wrapper.ERROR_CODE,cmnyMessageSource.getMessage("merchant.updatePassword.error", null));
        }


        UacUser uacUser = new UacUser();

        uacUser.setId(uacMerchant.getUserIdBind());
        uacUser.setLoginPwd(newPassWord);

        int update = userService.update(uacUser);
        /**
         * @author  chisj
         * @data    2020-12-03
         * @desc    清除token
         */
        if (update > 0) {
            uacUserTokenService.restTokenByUser(id);
        }

        return WrapMapper.wrap(Wrapper.SUCCESS_CODE,cmnyMessageSource.getMessage("operation.success", null),update);
    }

    @ValidateAnnotation
    @ApiOperation(httpMethod = "POST", value = "获取商家id")
    @RequestMapping(value = "/haveId", method = RequestMethod.POST)
    public Wrapper haveId(){


        UacMerchant uacMerchant = new UacMerchant();


        uacMerchant.setUserIdBind(getLoginAuthDto().getUserId());

        if(PublicUtil.isEmpty(uacMerchant.getUserIdBind())){
            return WrapMapper.wrap(Wrapper.ERROR_CODE,cmnyMessageSource.getMessage("merchant.user.null", null));
        }

        List<UacMerchant> select = merchantService.select(uacMerchant);

        if(PublicUtil.isNotEmpty(select)){
            return WrapMapper.wrap(Wrapper.SUCCESS_CODE,cmnyMessageSource.getMessage("operation.success", null),select.get(0).getId());
        }

        return WrapMapper.wrap(Wrapper.SUCCESS_CODE,cmnyMessageSource.getMessage("operation.success", null));
    }

    @ValidateAnnotation
    @ApiOperation(httpMethod = "POST", value = "查询商家服务类别")
    @RequestMapping(value = "/selectLevelId", method = RequestMethod.POST)
    public Wrapper selectLevelId(Long id){

        UacSecondLvelMerchantBind secondLvelMerchantBind = new UacSecondLvelMerchantBind();
        secondLvelMerchantBind.setMerchantId(id);
        List<UacSecondLvelMerchantBind> select = secondLvelMerchantBindService.select(secondLvelMerchantBind);




        return WrapMapper.wrap(Wrapper.SUCCESS_CODE,cmnyMessageSource.getMessage("operation.success", null),select);
    }


    @ValidateAnnotation
    @ApiOperation(httpMethod = "POST", value = "设定上下班时间")
    @RequestMapping(value = "/saveTime", method = RequestMethod.POST)
    public Wrapper saveTime(@RequestBody @Valid MerchantTimeDto merchantTimeDto){

        UacMerchant merchant = new UacMerchant();

        merchant.setUserIdBind(getLoginAuthDto().getUserId());




        UacMerchant one = merchantService.selectOne(merchant);

        if(PublicUtil.isEmpty(one)){
            return WrapMapper.wrap(Wrapper.ERROR_CODE,cmnyMessageSource.getMessage("merchant.user.null", null));
        }


        UacMerchant uacMerchant = new UacMerchant();

        BeanUtils.copyProperties(merchantTimeDto,uacMerchant);

        uacMerchant.setId(one.getId());


        int update = merchantService.update(uacMerchant);


        return WrapMapper.wrap(Wrapper.SUCCESS_CODE,cmnyMessageSource.getMessage("operation.success", null),update);
    }

    @ValidateAnnotation
    @ApiOperation(httpMethod = "POST", value = "手动上班")
    @RequestMapping(value = "/merchantOn", method = RequestMethod.POST)
    public Wrapper merchantOn() throws ParseException {


        //根据userId获取到商家对象
        UacMerchant merchant = new UacMerchant();

        merchant.setUserIdBind(getLoginAuthDto().getUserId());



        UacMerchant one = merchantService.selectOne(merchant);

        if(PublicUtil.isEmpty(one)){
            return WrapMapper.wrap(Wrapper.ERROR_CODE,cmnyMessageSource.getMessage("merchant.user.null", null));
        }

        //判断是否设定上下班时间
        if(PublicUtil.isEmpty(one.getOnTime())||PublicUtil.isEmpty(one.getOffTime())){
            return WrapMapper.wrap(Wrapper.ERROR_CODE,cmnyMessageSource.getMessage("merchant.time.null", null),false);
        }


        //判定当前时间是否是上班时间
        if(!OnOffTimeUtil.isBusiness(one.getOnTime(),one.getOffTime())){
            return WrapMapper.wrap(Wrapper.ERROR_CODE,cmnyMessageSource.getMessage("merchant.onTime.error", null),false);
        }


        //设定为上班状态

        one.setIsBusiness(1);

        one.setIsManual(0);


        redisTemplate.opsForValue().set(RedisKeyUtil.getUacMerchant(one.getId().toString()),one);
        int update = merchantService.update(one);


        return WrapMapper.wrap(Wrapper.SUCCESS_CODE,cmnyMessageSource.getMessage("operation.success", null),update);
    }

    @ValidateAnnotation
    @ApiOperation(httpMethod = "POST", value = "手动打烊")
    @RequestMapping(value = "/merchantOff", method = RequestMethod.POST)
    public Wrapper merchantOff(){

        UacMerchant merchant = new UacMerchant();

        merchant.setUserIdBind(getLoginAuthDto().getUserId());



        UacMerchant one = merchantService.selectOne(merchant);

        if(PublicUtil.isEmpty(one)){
            return WrapMapper.wrap(Wrapper.ERROR_CODE,cmnyMessageSource.getMessage("merchant.user.null", null));
        }


        one.setIsBusiness(0);

        one.setIsManual(1);


        redisTemplate.opsForValue().set(RedisKeyUtil.getUacMerchant(one.getId().toString()),one);
        int update = merchantService.update(one);


        return WrapMapper.wrap(Wrapper.SUCCESS_CODE,cmnyMessageSource.getMessage("operation.success", null),update);
    }

    @ValidateAnnotation
    @ApiOperation(httpMethod = "POST", value = "查询在离线状态和上下班时间")
    @RequestMapping(value = "/selctIsTime", method = RequestMethod.POST)
    public Wrapper selctIsTime(){



        //根据userId获取到商家对象
        UacMerchant merchant = new UacMerchant();

        merchant.setUserIdBind(getLoginAuthDto().getUserId());


        UacMerchant one = merchantService.selectOne(merchant);

        if(PublicUtil.isEmpty(one)){
            return WrapMapper.wrap(Wrapper.ERROR_CODE,cmnyMessageSource.getMessage("merchant.user.null", null));
        }

        MerchantTimeVo merchantTimeVo = new MerchantTimeVo();

        if(PublicUtil.isEmpty(one.getOnTime())||PublicUtil.isEmpty(one.getOffTime())){
            return WrapMapper.wrap(Wrapper.ERROR_CODE,cmnyMessageSource.getMessage("merchant.time.null", null),merchantTimeVo);
        }


         merchantTimeVo.setOnTime(one.getOnTime());
         merchantTimeVo.setOffTime(one.getOffTime());


        if(one.getIsBusiness().equals(1)){
            merchantTimeVo.setBusiness(true);
        }


        return WrapMapper.wrap(Wrapper.SUCCESS_CODE,cmnyMessageSource.getMessage("operation.success", null),merchantTimeVo);
    }


    /*@ValidateAnnotation
    @ApiOperation(httpMethod = "POST", value = "个人app查询附近商家")
    @RequestMapping(value = "/selectPersonage ", method = RequestMethod.POST)
    public Wrapper selectPersonage(@RequestBody @Valid MerchantPersonageSelectDto merchantPersonageSelectDto){

        double minlat = 0;//定义经纬度四个极限值。
        double maxlat = 0;
        double minlng = 0;
        double maxlng = 0;
        //我数据保存的经纬度是string，所以要转一下类型方便计算距离。  shopParam是传参。
        double longitude = Double.parseDouble(merchantPersonageSelectDto.getLongitude());
        double latitude = Double.parseDouble(merchantPersonageSelectDto.getLatitude());

        // 先计算查询点的经纬度范围
        double r = 6371;// 地球半径千米
        double dis = merchantPersonageSelectDto.getDistance();// 距离(单位:千米)，查询范围
        double dlng = 2 * Math.asin(Math.sin(dis / (2 * r))
                / Math.cos(longitude * Math.PI / 180));
        dlng = dlng * 180 / Math.PI;// 角度转为弧度
        double dlat = dis / r;
        dlat = dlat * 180 / Math.PI;
        if (dlng < 0) {
            minlng = longitude + dlng;//拿到最大经度和最小经度
            maxlng = longitude - dlng;
        } else {
            minlng = longitude - dlng;
            maxlng = longitude + dlng;
        }
        if (dlat < 0) {
            minlat = latitude + dlat;//拿到最大纬度和最小纬度
            maxlat = latitude - dlat;
        } else {
            minlat = latitude - dlat;
            maxlat = latitude + dlat;
        }


        System.out.println("最大经度："+maxlng+"最小经度："+minlng);
        System.out.println("最大经度："+maxlat+"最小经度："+minlat);


        final List<MerchantVo> shops = Lists.newArrayList();//定义一个空 list保存范围内的店铺
        List<MerchantVo> shopList=merchantService.selectPersonage(merchantPersonageSelectDto);
        //final List<UacMerchant> shopList = merchantService.selectAll();//查询所有商铺
        for (MerchantVo shop:shopList) {
            double _long = Double.parseDouble(shop.getLongitude().toString());//拿到店铺的坐标，判断是否在这个范围内
            double _lat = Double.parseDouble(shop.getLatitude().toString());
            if (_long >= minlng && _long <= maxlng && _lat >= minlat && _lat <= maxlat){
                shops.add(shop);//将在这个范围内的店铺添加到一个空list中。
            }
        }
        Map<MerchantVo,Double> map = new HashMap<MerchantVo, Double>();//定义一个空的map存储店铺
        //计算范围内每个店铺距离给定坐标的距离
        for (MerchantVo _shop:shops) {
            Double distance = LocationUtils.getDistance(Double.parseDouble(_shop.getLatitude().toString()),Double.parseDouble(_shop.getLongitude().toString()),latitude,longitude);
            System.out.println("店铺名称:"+_shop.getMerchantName()+"经度:"+_shop.getLongitude()+"纬度:"+_shop.getLatitude()+"距离:"+distance);
            map.put(_shop,distance);//将计算出来的距离作为value，该店铺作为key
        }
        final List<MerchantVo> list = Lists.newArrayList();//存储排序之后的店铺
        //这里使用Java8的map根据value排序，距离最近排序，按value排序，升序
        Map<MerchantVo,Double> doubleMap = map
                .entrySet()
                .stream()
                .sorted(comparingByValue())
                .collect(
                        toMap(e -> e.getKey(), e -> e.getValue(), (e1, e2) -> e2,
                                LinkedHashMap::new));
        for (Map.Entry<MerchantVo, Double> entry:doubleMap.entrySet()) {
            list.add(entry.getKey());//循环map拿到key并保存到list中。
        }







        for (MerchantVo merchantVo : shopList) {
            UacSecondLvelMerchantBind uacSecondLvelMerchantBind = new UacSecondLvelMerchantBind();
            uacSecondLvelMerchantBind.setMerchantId(merchantVo.getId());
            List<UacSecondLvelMerchantBind> select = secondLvelMerchantBindService.select(uacSecondLvelMerchantBind);
            ArrayList<Long> longs = new ArrayList<>();
            for (UacSecondLvelMerchantBind secondLvelMerchantBind : select) {
                longs.add(secondLvelMerchantBind.getSecondLevelId());
            }
            merchantVo.setSecondLevelIds(longs);
        }
        PageInfo<MerchantVo> merchantVoPageInfo = new PageInfo<>(shopList);


        return WrapMapper.wrap(Wrapper.SUCCESS_CODE,cmnyMessageSource.getMessage("operation.success", null),merchantVoPageInfo);
    }*/


}
